﻿namespace Atomic.Mvc.Filters
{
    using System.Linq;
    using System.Web.Mvc;

    using Atomic.Mvc.Properties;
    using Atomic.Mvc.ViewEngines;

    /// <summary>
    /// 视图过虑器。
    /// </summary>
    /// <remarks>
    /// 在控制器里，使用View("~/Views/Home/Index.cshtml")这样指定了具体的路径时，没有定位到插件里，而是定位到了外部文件。
    /// </remarks>
    public class ViewAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Action 方法执行结束时处理。
        /// </summary>
        /// <param name="filterContext">提供 System.Web.Mvc.ActionFilterAttribute 类的 ActionExecuted 方法的上下文。</param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);

            var result = filterContext.Result as ViewResult;

            if (result != null)
            {
                result.ViewName = this.GetViewFilePath(filterContext, result.ViewName);
            }
        }

        /// <summary>
        /// 根据视图名称获得具体位置。
        /// </summary>
        /// <remarks>
        /// 1.先判断该视图是否存在于插件里。
        /// 2.存在则把路径定位到插件里，不存在则返回原数据。
        /// </remarks>
        /// <param name="filterContext">提供 System.Web.Mvc.ActionFilterAttribute 类的 ActionExecuted 方法的上下文。</param>
        /// <param name="viewName">视图名称。</param>
        /// <returns>视图具体位置。</returns>
        private string GetViewFilePath(ActionExecutedContext filterContext, string viewName)
        {
            string pluginName = string.Empty;
            string pluginFolder = string.Empty;

            if (filterContext.RouteData.Values.ContainsKey(Resources.VIEW_PLUGIN_NAME))
            {
                pluginName = filterContext.RouteData.GetRequiredString(Resources.VIEW_PLUGIN_NAME);
            }

            if (filterContext.RouteData.Values.ContainsKey(Resources.VIEW_PLUGIN_FOLDER))
            {
                pluginFolder = filterContext.RouteData.GetRequiredString(Resources.VIEW_PLUGIN_FOLDER);
            }

            if (!string.IsNullOrWhiteSpace(pluginName) && !string.IsNullOrWhiteSpace(pluginFolder))
            {
                var viewsName = PluginLayout.GetLayout(pluginName, pluginFolder, viewName);

                if (viewsName != null && viewsName.Length > 0)
                {
                    viewName = viewsName.FirstOrDefault();
                }
            }

            return viewName;
        }
    }
}